// Tcp监听
package main

import (
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
)

type Listener struct {
	//port     int
	cfg         *Config
	dbo         *DBOperation
	connManager *ConnManager
	upgrader    *websocket.Upgrader
}

const (
	BUFFERSIZE  int = 1024
	DEFAULTPORT int = 9600
)

func Listen(cfg *Config, dbo *DBOperation, cm *ConnManager) {
	if cfg.Port == 0 {
		cfg.Port = DEFAULTPORT
	}
	l := NewListener(cfg, dbo, cm)
	go l.listen()
}

func NewListener(cfg *Config, dbo *DBOperation, cm *ConnManager) *Listener {
	upgrader := websocket.Upgrader{
		ReadBufferSize:  BUFFERSIZE,
		WriteBufferSize: BUFFERSIZE,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
	l := Listener{cfg: cfg, dbo: dbo, connManager: cm, upgrader: &upgrader}

	return &l
}

func (p *Listener) listen() {
	sPort := fmt.Sprintf(":%d", p.cfg.Port)
	zLog(nil, "开始监听端口:", sPort, " HTTPS:", p.cfg.HTTPS)

	http.HandleFunc("/monitor", p.handler)

	var err error
	if p.cfg.HTTPS {
		err = http.ListenAndServeTLS(sPort, p.cfg.CertFile, p.cfg.KeyFile, nil)
	} else {
		err = http.ListenAndServe(sPort, nil)
	}
	if err != nil {
		zLog(nil, "HTTPS监听失败:", err)
	} else {
		zLog(nil, "HTTPS监听成功！")
	}
}

func (p *Listener) handler(w http.ResponseWriter, r *http.Request) {
	var mc *MonitorConn = nil
	zLog(nil, "monitor handler start......")
	ws, err := p.upgrader.Upgrade(w, r, nil)
	if err != nil {
		zLog(nil, err.Error())
		return
	}
	defer func() {
		var errMsg string

		if mc != nil && mc.userid != "" {
			errMsg = fmt.Sprintf("%s 用户ID：%s", ws.RemoteAddr().String(), mc.userid)
		} else {
			errMsg = ws.RemoteAddr().String()
		}
		if err := recover(); err != nil {
			zLog(nil, errMsg, " 捕捉到异常:", err)
		}

		mc.exitChan <- true
		p.connManager.Remove(mc)

		zLog(nil, errMsg, " 已断开")
		ws.Close()
	}()

	zLog(nil, "monitor handler ", ws.RemoteAddr().String(), " 已连接")
	mc = NewMonitorConn(ws, p.dbo, p.cfg.CheckAccessUrl)

	p.connManager.Add(mc)

	mc.Run()
}
